var DEFAULT_IMAGE_WIDTH = 200;
var onSize = {
    list   : [],
    add    : function (i) {if (i) this.list.push (i);},
    invoke : function () {for (var x=0;x<this.list.length;x++)this.list[x].invoke(); },
    clear  : function () { this.list = [] }
}

function connect (endpoint, callback, method, data) // connect                                                        
{
    var connector=XmlHttp.create();
    connector.open(method || "GET", endpoint, callback ? true : false);     
    if (callback)
    {                                                                                                                                                                                                
        connector.onreadystatechange = function ()                                              
        {                                              
            if (connector.readyState == 4)                                              
            {     
                callback (connector.responseText);                                              
            }  
        }                                          
    }
    connector.send( data );       
    if (callback) return true;  
    return connector.responseText;    
} // connect

function Touch(id) {
    var element = $(id);
    if (!element) alert (id + ' not found!');
   /* element.ontouchstart = function () {
        event.preventDefault ();
        var t = event.touches[0];
        alert (t.pageX + 'x' + t.pageY);
    }*/
}

// article-gallery methods
var bPlaying = false; 
function LoadPicturebyKey(key) {  
    var gn   = $('gn').value;
    var uri  = '/article-gallery/'+gn+'/0/0/'+key+'/show';
    var done = function (id) { 
        LoadArticleURL (id, {group:gn,index:key}); 
    }
    if ($('box')) $('box').style.border="solid 1px gray";
    $('drp').disabled = true;
    connect (uri, done);
}
function LoadPicturebyGroup(gn, key) {  
    var uri  = '/article-gallery/'+gn+'/0/0/'+key+'/show';
    var done = function (id) { 
       // var w = '/request/watch/id/' + id;
        var u = '/favorites/home/group/'+gn; 
        if (id=='OK') return location.href = u;
        WatchProgressById(id, u);
    } 
    connect (uri, done);
}

function LoadArticleURL (id, object)
{ 
  //  var w = '/request/watch/id/' + id;
    var u = '/request/picture/name/'+object.group+'/index/'+object.index+'';
    var f = $('box') ? function () { preload ($('box'), u, attach); } : function () { displayPicture(u); } 
    var c = function () {  $('drp').disabled = false; f() } //   } 
    if (id=='OK') return c();
    WatchProgressById(id, false, c);
} 

function ArticlePlay (element)
{
    var name = element || 'pa';
    bPlaying = !bPlaying;
    if ($(name)) $(name).innerHTML = bPlaying ? 'Stop' : 'Play';
    ServiceBus.OnPlay ();
    ArticleGo ()
}

function ArticleGo ()
{ 
    if (!bPlaying) return;
    ArticleAdvance (1); 
}

function ArticleAdvance (i)
{
    var d=$('drp');
    d.selectedIndex += i;
    LoadPicturebyKey(d.options[d.selectedIndex].value); 
}

Queue=[], Cache={};
function N() {

           var f = Queue.pop();
         if (f)  f();// setTimeout (f, 500);	
} 

function PreviewRequest (Id, Key, Group) 
{   
    var count   = Math.floor(PREVIEW_COUNT / 2)
    var Element;
    if (!(Element = $('p.preview.' + Id)))
        if (!(Element = $('pr' + Id))) return;
                
    var Started = Queue.length > 2;
    var Request = '/article-gallery/'+Group+'/0/0/'+Key+'/show';
    var Picture = '/request/picture/name/'+Group+'/index/'+Key+'/thumb/64/rect/rect';
    var Px      = Id == count ? "2px" : "1px";

    var show = function () { //alert (Picture)

try {
// document.title = Queue.length;
  //      Element.style.background     = "url(" + Picture + ")";
        Element.style.border = Cache[Picture] ? ("solid 1px "+COLOR_CACHED+"") : ("solid 1px "+COLOR_RESPOND+""); 
       if (Element.id=='pr'+count) Element.style.border = "solid 2px "+COLOR_ACTIVE+"" ;
        Cache [Picture] = Picture;

        
  //          if (Queue.length > 0)Element.onload = Queue.pop();
  //      Element.onerror = Element.onload;
        if (Element.id.indexOf('preview') > 0) {
            return Element.src = Picture;
        }
        Element.innerHTML="<img width='48' onerror='N()' onload='N()' src='"+Picture+"'/>";
} catch (ex) { alert(ex.message); }
    }
    var done = function (response) { 
    	if (response=='OK') return show();
        Element.style.border = "solid "+Px+" "+COLOR_QUEUED+"";
        WatchProgressById(response, null, show, 'debug'+Id, true, THREAD_IMLOAD);
    }
    
    Queue.push (function () { 
    	if (Cache[Picture]) return show();
       //  this.onload = null;
        Element.style.border = "solid "+Px+" "+COLOR_REQUEST+"";
        connect (Request, done);});  
    Element.style.border = "solid "+Px+" "+COLOR_REQUEST+"";
    if (Started) return;
    Queue[0]();
}


function AsyncRequest (Request, Target, Element) 
{ 
    var done = function (response) { // if(!confirm([Request,response])) return;
        if (response=="OK") return location.href = Target;
        WatchProgressById(response, Target, null, Element);
    }
    if (Element) $(Element).innerHTML = "<img align='absmiddle' src='/images/clock.png'/> " 
                                      + "Connecting to server...";
    connect (Request, done);
}

function LoadPageByPattern (URL, Element, Target) 
{
    var here = location.href.split('/'), there = URL.split('/'), key = there.pop();
    here.pop();
    here.push (key);
    AsyncRequest (URL, Target || here.join ('/'), Element)
}

function unwrap (message)
{
    var object={}, scissor=XmlDocument.create();
    if (message.length > 0 && scissor.loadXML(message)) { 
        var Node = scissor.documentElement.childNodes;
        for(var i=0;i<Node.length;i++) {
            if (Node[i].nodeName.indexOf('#') < 0) { 
                object[Node[i].nodeName] = Read(Node[i]);
            }
        }
    }
    return object;
}  

var Read = function (element) { return element.firstChild?element.firstChild.nodeValue:element.nodeValue; };



  var Carousel ;

function LoadCarousel(group, idset) {
    Carousel = {
        list    : idset,
        group   : group, 
        index   : 0,
        get     : function (i) {
            var current = this.index
            this.index = i;
            this.cancel = false;
            ServiceBus.OnSlid (this, { use : current });
            this.cancel = true;
        },
        next    : function () {
            if (this.cancel) return;
            if (this.timer) clearTimeout (this.timer);
            this.timer = setTimeout (ServiceBus.OnSlid, 7500)
        },
        invoke  : function (sender, e) {
            if (this.cancel) return;

            var first  = this.list [this.index > -1 ? this.index : this.list.length - 1];
            var second = this.list [this.index < (this.list.length - 1) ? (this.index + 1) : 0];
            if (e && e.use) {
                first  = this.list[e.use];
                second = this.list[this.index];
            } 
            var uri    = "/request/icon/group/" + this.group + "/slide/" + first.id + "," + second.id + "";  
            var im     = new Image ();
            im.onload = function() {
                $('vp').style.background = "url(" + this.src + ")";
                GoSlide ('vp');
            }
            im.src = uri;
            if (e && e.use) return;
            this.index ++;
            if (this.index > this.list.length  - 1)
                this.index = 0;
        }
    }

    ServiceBus.Subscribe ('OnSlid', Carousel);
    var titler = {
        list    : idset, 
        element : $('p.subject'), 
        invoke  : function (sender, e) {
           var text = this.list[Carousel.index].subject;
           var id   = this.list[Carousel.index].id;
           var uri  = "/favorites/load/group/" + Carousel.group + "/page/1/key/" + id + "/item/" + id + "";
           this.element.onclick = function () { location.href = uri };
           this.element.innerHTML = text; 
        } 
    }
    var dotter = {
        list    : idset, 
        element : $('p.dot'), 
        invoke  : function (sender, e) {
           var text = [];
           var f = function (o) { return '<a href="javascript:Carousel.get('+o+')" style="color:white;text-decoration:none;">&bull;</a>' }
           for (var i=0;i<this.list.length;i++)
               text.push (i==Carousel.index?'<b>&bull;</b>':f(i));
           this.element.innerHTML = text.join('&nbsp;');  
        } 
    }
    ServiceBus.Subscribe ('OnSlid', titler, dotter);
    ServiceBus.OnSlid();
}

function GoSlide(element, x) {
    setTimeout (function() { GoSlideEx(element, x) }, 250);
}

function GoSlideEx(element, x) {
    var i = x||1, z = 77; 
        i += z;
        $(element).style.backgroundPosition = "-" + i + "px 0px";
    if (i > 768) return  Carousel.next();
    setTimeout (function() { GoSlideEx(element, i) },250);
}


var threadee = {}, running={};
function Progbar (value, most, caption) {
    var percent = 1 - (value / most), width = Math.floor (percent * 200);
    var image = "<img width='120' height='10' src='/request/icon/progress/"+value+","+most+"'/>";
    return caption + "<div class='progress' style='background-position:-" + width + "px 0px'></div>";
}

function OnJobComplete(job, target, element, messagebox) {
    var done = function (response) {
        if (!response) return;
        $(element).innerHTML = "<img align='absmiddle' src='/images/ok.png'/> " 
                             + "Search complete. <a href='"+target+"'>Click here to see your results.</a>"; 
        $(messagebox).innerHTML = "";
    }
    $(messagebox).innerHTML = "Please wait...";
    var URL = '/request/fullsearch/unpersist/' + job;
    connect (URL, done);
}
var THREAD_ACTIVE  = 1;
var THREAD_LOCKED  = 3;
var THREAD_CANCEL  = 2;
var THREAD_IMLOAD  = 4;
var IPHONE_UI = false;

function WatchProgressById(ID, Target, Callback, Element, Long, State, Icon) {  
    var URL   = '/request/watch/id/' + ID;
    var state = State || (Long?THREAD_LOCKED:THREAD_ACTIVE);
    for (var x in running)
        if ((running[x].state==THREAD_IMLOAD && State != THREAD_IMLOAD) || 
            (running[x].state!=THREAD_LOCKED && !Long))
            running[x].state = THREAD_CANCEL;
    var thread={ id:ID, state:state, obj:{}, tries:0, icon:Icon }
    running['i'+ID]=thread;
    WatchProgress(URL, Target, Callback, Element, Long)
}

function OnWatchComplete(Target, Element) {
    $(Element).innerHTML = "<img align='absmiddle' src='/images/ok.png'/> " 
                         + "Download complete. Please wait...";  
    setTimeout (function() { location.href = Target }, 1)
}

function WatchProgress(URL, Target, Callback, Element, Long) {  
    var doWatch    = function () { WatchProgress(URL, Target, Callback, Element, Long); }
    var messagebox = Element || 'dbx';
    var onComplete = Callback || function () { OnWatchComplete(Target, messagebox) };
    var message    = connect(URL);  // alert (message);
    var caption    = "";//"<xmp>" + message + "</xmp>";

 // if ($(messagebox)) $(messagebox).innerHTML = "Loading...";
    var object     = unwrap (message);
    var validate   = function (id) {
        var runner;
        if (runner=running['i'+id])
            if (runner.state==THREAD_CANCEL)
                return;// $(messagebox).innerHTML = "Operation ("+id+") cancelled.";

        return onComplete ();
    }

    caption += "<table cellspacing='0' width='100%'>";
    var wide  = function(x,y) {return "<tr><td class='row' nowrap>"+x+"</td><td width='100%' class='row' valign='bottom'>"+y+"</td></tr>"; }
    var thin  = function (x,y) { return x +  y + '<br/>' };
    var f = Long ? wide : thin;
    if (IPHONE_UI) f = function (x,y) { return x + '<br/>' + y };
    if (object.state) {
        var runner = running['i'+object.id]; 
        if (runner) { 
            ServiceBus.OnProgress (null, { icon : runner.icon, object : object });
        }

        if ($(messagebox)) $(messagebox).innerHTML = object.state;
        if (object.state == 'COMPLETE') return validate(object.id);
         
            if (runner.state==THREAD_CANCEL)
                return;// $(messagebox).innerHTML = "Operation ["+object.id+"] cancelled.";
     //   runner.tries ++;
     //    $(messagebox).innerHTML = "Operation ["+runner.tries+"] running...";

        var im = $('i.' + object.id);
        if (im) {
            caption += f(object.value + ' of ' + object.max, object.caption);
            im.src = "/request/icon/arc/"+object.value+","+object.max+"";
        }
        else caption += f(Progbar(object.value, object.max, object.value + ' of ' + object.max) 
                                     , object.caption);
        var tmp = object;
        for (var x=0;x<10;x++) {
            var text  = tmp['caption_' + x];
            if (!(text && text.length > 0)) {
                if (text = runner.obj['caption_' + x]) { 
                    if (text.length > 0) { 
                        tmp = runner.obj;
                    } else continue;
                } else continue;
            }
            var value = tmp['value_' + x];
            var state = tmp['state_' + x];
            var limit = tmp['max_' + x];

            for (var n in tmp)
               if (tmp[n] && tmp[n].length > 0)
                   runner.obj[n] = tmp[n];
 
            caption += f( Progbar(value, limit, value + ' of ' + limit) 
                                  , text);
            tmp = object;
        }
        caption += "</table>";
        if ($(messagebox)) $(messagebox).innerHTML = caption ;//+ "!!";
        else document.title = caption;
    }
    setTimeout (doWatch, 3500); 
} 

function $(i) { return document.getElementById(i); };
function ratio(im,spec)
{
    var w=im.width,h=im.height,r=w/h,d=spec||DEFAULT_IMAGE_WIDTH;
    return w>h?{x:d,y:d/r}:{y:d,x:d*r}
}

function preload (im, src, cb)
{
    if (!im) return alert("No image found!");
    var that=im,callback=cb,bg = new Image();
    var r=Math.random()*100;
    bg.onload = function ()
    {
        that.onload = null;
        var sz = ratio (this);
        that.width  = sz.x;
        that.height = sz.y;
        that.src = this.src;
        that.style.border="solid 1px";
        that.style.borderColor = 'white gray gray white';
         setTimeout(displayPreview, 100);
        ServiceBus.OnSlideComplete();

        if (bPlaying) setTimeout (ArticleGo, 7500);
        if (callback) callback();
    }  
    im.style.border="solid 1px cyan";   
    bg.src = src;// + '?' + r;
}  

function attachPicture (image)
{
    preload (image, image.className, attach);
}  

function attach ()
{ 
    var picture=$('box')  
    if (picture)
    {
        picture.invoke = function ()
        {
            var o = { w:Math.min(window.innerWidth,768),h:window.innerHeight};   
            var ro = o.w / o.h, ri = this.width / this.height, ok = (ro > 1 && ri > 1) || (ro <= 1 && ri <= 1);
            sz = ratio(this, (ok?Math.max(o.w,o.h):Math.min(o.w,o.h)) - 80);
            this.width  = sz.x;
            this.height = sz.y; 
        }	
        onSize.add (picture);
    }  
    window.onresize = function ()
    {
        onSize.invoke ();
    } 
    onSize.invoke (); 
}

function displayPreview()
{
    var count = Math.floor(PREVIEW_COUNT / 2), limit = PREVIEW_COUNT - count;
    var gn   = $('gn').value, d=$('drp'), n=d.selectedIndex;
    Queue = [];
    for (var z=-1,i=n-count;i<n+limit;i++) {
        z++;
        var Element = $('pr' + z);
        if (Element) Element.innerHTML = '';
        if (!d.options[i]) continue;
        var Key = d.options[i].value; 
        PreviewRequest (z, Key, gn);
    }

    if ($('pz')) $('pz').innerHTML = d.options[n].text;
}
var toggled = false;
function togglePreview(on) {
    var p=$('pane.info');
    p.style.display = on || p.style.display == 'none' ? '' : 'none';
    toggled =!(p.style.display=='none');
}

var previewer;
function displayPicture(address, cb) {
    previewer  = {
        pane   : $('pane'),
        ondone : cb,
        image  : new Image (),
        width  : 1,
        height : 1,
        src    : null,
        invoke : function () { 
            var o = { w:window.innerWidth,h:window.innerHeight };   
            var ro = o.w / o.h, ri = this.width / this.height, ok = (ro > 1 && ri > 1) || (ro <= 1 && ri <= 1);
            sz = ratio(this, (ok?Math.max(o.w,o.h):Math.min(o.w,o.h)) - 80);
            this.pane.style.width  = sz.x + "px";
            this.pane.style.height = sz.y + "px";
            this.pane.style.background = "url(" + this.src + ")";
            this.pane.style.backgroundSize = sz.x + "px " + sz.y + "px"; 
            ServiceBus.OnSlideComplete();
            setTimeout(displayPreview, 100);;
            if (this.ondone) this.ondone ();
        },
        init   : function (src) {
            this.src = src;
            this.image.onload = this.onload;
            this.image.src = this.src;
        },
        load   : function () {
            this.invoke (); 
            togglePreview(toggled);
            if (bPlaying) setTimeout (ArticleGo, 5000);
        },
        onload : function () {
            previewer.width  = this.width;
            previewer.height = this.height;
            previewer.load();
        }
    }
    previewer.init (address);
    
    window.onresize = function ()
    {
        previewer.invoke ();
    } 
}







